#include "GetCameraFrame_Thread.h"
#include <QDebug>

static QSharedMemory* g_pShareVideo = nullptr;
static QSharedMemory* g_pShareGetVideo = nullptr;

GetCameraFrame_Thread::GetCameraFrame_Thread(QObject *parent)
    : QThread(parent)
{
    m_bCameraOpen = false;
    m_bExit = false;
    this->start();
}

GetCameraFrame_Thread::~GetCameraFrame_Thread()
{
    m_bExit = false;
    this->terminate();
}

void GetCameraFrame_Thread::run()
{
    // 打开摄像头
    if(m_cvCapture.isOpened()){
        m_cvCapture.release();
    }
    m_bCameraOpen = m_cvCapture.open(0);
    if(m_cvCapture.isOpened()){
        m_cvCapture.set(CV_CAP_PROP_FOURCC, CV_FOURCC('M', 'J', 'P', 'G'));
        m_cvCapture.set(CV_CAP_PROP_FRAME_WIDTH, 1600);
        m_cvCapture.set(CV_CAP_PROP_FRAME_HEIGHT,1200);
        qDebug() << "m_cvCapture CONFIG Param=================: "
                 << m_cvCapture.get(CV_CAP_PROP_FPS)
                 << m_cvCapture.get(CV_CAP_PROP_FRAME_WIDTH)
                 << m_cvCapture.get(CV_CAP_PROP_FRAME_HEIGHT);
    }
    // 创建共享内存
    if(m_bCameraOpen){
        if(nullptr == g_pShareVideo){
            g_pShareVideo = new QSharedMemory("Robot_Camera_Live");
            g_pShareVideo->create(1600*1200*3+5);
        }

        while (!m_bExit) {
            cv::Mat srcFrame, cloneFrame;
            m_cvCapture.read(srcFrame);
            cv::cvtColor(srcFrame, cloneFrame, CV_BGR2RGB);
            if(!g_pShareVideo->isAttached()){
                g_pShareVideo->attach();
            }
            g_pShareVideo->lock();
            int *pMemData = (int*)g_pShareVideo->data(); //may be null
            pMemData[0] = cloneFrame.cols;
            pMemData[1] = cloneFrame.rows;
            int nFlag = cloneFrame.channels() * 8;
            size_t nBytes = cloneFrame.cols * cloneFrame.rows * nFlag / 8;
            memcpy((void*)(pMemData+2), (void*)cloneFrame.data, nBytes);
            g_pShareVideo->unlock();
            QThread::msleep(10);
        }

        m_cvCapture.release();
    }
    qDebug() << "摄像头线程退出";
}

bool GetCameraFrame_Thread::GetVideoFrameQImage(QImage &Img)
{
    bool bResult = false;
    if (nullptr == g_pShareGetVideo) {
        g_pShareGetVideo = new QSharedMemory("Robot_Camera_Live");
    }
    if (!g_pShareGetVideo->isAttached()) {
        g_pShareGetVideo->attach();
    }
    if (g_pShareGetVideo->isAttached()) {
        int nWidth = 0; int nHeight = 0;
        static uint8_t *buffer = new uint8_t[1600*1200*3+5];
        g_pShareGetVideo->lock();
        int *pMemData = nullptr;
        pMemData = (int*)g_pShareGetVideo->data();
        if(nullptr != pMemData) {
            nWidth = pMemData[0];
            nHeight = pMemData[1];
            memcpy((void*)buffer, (void*)(pMemData+2), nWidth*nHeight*3);
        }
        g_pShareGetVideo->unlock();
        if(nWidth > 0 && nHeight > 0) {
            QImage tmpImg(buffer,nWidth,nHeight,QImage::Format_RGB888);
            Img = tmpImg.scaled(nWidth/3, nHeight/3);
            bResult = true;
        }else{
            bResult = false;
            qDebug() << "GetVideoFrameQImage g_pShareGetVideo error";
        }
    }
    return bResult;
}
